// "use strict";
const { log } = console;
// const person = {
//   name: "zhoulang",
//   age: 30,
// };

// const personProxy = new Proxy(person, {
//   get(target, property) {
//     return property in target ? target[property] : "default";
//   },
//   set(target, property, value) {
//     if (property === "age") {
//       if (!Number.isInteger(value)) {
//         throw new TypeError(`${value} is not an int`);
//       }
//     }
//     log("personProxy => ", target, property, value);

//     target[property] = value;
//   },

//   has(target, property) {
//     log(target, property);
//   },
// });

// personProxy.age = 100;

// personProxy.gender = true;

// log(personProxy.name);
// log(personProxy.xxx);

// has
// "name" in personProxy;

// 对数组的操作
// const list = [];

// const listProxy = new Proxy(list, {
//   set(target, property, value) {
//     log(target, property, value);
//     target[property] = value;
//     return true;
//   },
// });
// log(listProxy.push);
// listProxy.push(1);
// log(list);
const obj = {
  prop: 42,
};

// Object.freeze(obj);

const objProxy = new Proxy(obj, {
  // set(target, property, value) {
  //   target[property] = value;
  // },
});

objProxy.name = 1;
log(objProxy);

// 总结: Proxy 是一个类，用于对指定的对象在访问/设置其属性的时候做一层代理，来实现自定义行为。
// 它不同于 Object.defineProperty,
// 1. Object.defineProperty 是对指定对象上的具体属性进行得，而 Proxy 是对
// 这个对象进行的，无需指定到具体的属性，所以 Proxy 相对于 Object.defineProperty 是可以观测到动态添加到
// 指定对象上的属性得,
// 2. Object.defineProperty 只能监视属性的 get、set, Proxy 可以监视对象的更多操作， 如 枚举、获取对象的 keys、
// 使用 in 操作符判断对象上是否有指定的属性、删除对象上的属性等。并且由于 Proxy 是对整个对象的监听，所以对数组的操作，也可以完美的控制。
// 3. Object.defineProperty 是对当前对象的操作， Proxy 是对一个对象进行了代理，返回的是一个新的对象,将对这个新对象的操作转发给原有对象
//
// 注意点:
// 1. 严格模式下，在 set 中操作成功需要返回一个 true 值，否则会报 TypeError
// 2. 对于不可配置或不可写的目标属性，set 操作不会改变它的值，比如 Object.freeze 之后的对象

// 问题: 在数组 set 的时候没有返回值，
// 使用 push 方法f赋值会导致 TypeError, 使用 下标方式赋值则不会出错

// 参考: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Proxy
